#include <stdio.h>

#include <string.h>
#include <sys/types.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>
#include <assert.h>


#include <termios.h>
#include <unistd.h>
//#include <syswait.h> 
//#include <syswait.h>
//#include <linux/delay.h>

#include <stdlib.h>
#define uint  unsigned int
#define uchar unsigned char
#define MAX_X 27
#define MAX_Y 14
//////////////////////////////////////////////////////////////////////


//#define  TEST_LCD




int fd;
/*打开串口函数*/

int open_port(int fd,int comport)

{

    char *dev[]={"/dev/ttySAC0","/dev/ttyS1","/dev/ttyUSB0"};

    long vdisable;

    if (comport==1)//串口 1

    {

        fd = open( "/dev/ttySAC1", O_RDWR|O_NOCTTY|O_NDELAY);

        if (-1 == fd){

            perror("Can't Open Serial Port");

            return(-1);

        }

    }

    else if(comport==2)//串口 2

    {

        fd = open( "/dev/ttySAC2", O_RDWR|O_NOCTTY|O_NDELAY);

        if (-1 == fd){

            perror("Can't Open Serial Port");

            return(-1);

        }

    }

    else if (comport==3)//串口 3

    {

        fd = open( "/dev/ttySAC3", O_RDWR|O_NOCTTY|O_NDELAY);

        if (-1 == fd){

            perror("Can't Open Serial Port ttyUSB0");

            return(-1);

        }

    }


    printf("wenjian=%d\n",fd);

    /*恢复串口为阻塞状态*/

    if(fcntl(fd, F_SETFL, 0)<0)

        printf("fcntl failed!\n");

    else

        printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));

    /*测试是否为终端设备*/

    if(isatty(STDIN_FILENO)==0)

        printf("standard input is not a terminal device\n");

    else

        printf("isatty success!\n");

    printf("fd-open=%d\n",fd);

    return fd;

}



int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

    struct termios newtio,oldtio;

    /*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/

    if ( tcgetattr( fd,&oldtio) != 0) {

        perror("SetupSerial 1");

        return -1;

    }

    bzero( &newtio, sizeof( newtio ) );

    /*步骤一,设置字符大小*/

    newtio.c_cflag |= CLOCAL | CREAD;

    newtio.c_cflag &= ~CSIZE;

    /*设置停止位*/

    switch( nBits )

    {

    case 7:

        newtio.c_cflag |= CS7;

        break;

    case 8:

        newtio.c_cflag |= CS8;

        break;

    }

    /*设置奇偶校验位*/

    switch( nEvent )

    {

    case 'O': //奇数

        newtio.c_cflag |= PARENB;

        newtio.c_cflag |= PARODD;

        newtio.c_iflag |= (INPCK | ISTRIP);

        break;

    case 'E': //偶数

        newtio.c_iflag |= (INPCK | ISTRIP);

        newtio.c_cflag |= PARENB;

        newtio.c_cflag &= ~PARODD;

        break;

    case 'N': //无奇偶校验位

        newtio.c_cflag &= ~PARENB;

        break;

    }

    /*设置波特率*/

    switch( nSpeed )

    {

    case 2400:

        cfsetispeed(&newtio, B2400);

        cfsetospeed(&newtio, B2400);

        break;

    case 4800:

        cfsetispeed(&newtio, B4800);

        cfsetospeed(&newtio, B4800);

        break;

    case 9600:

        cfsetispeed(&newtio, B9600);

        cfsetospeed(&newtio, B9600);

        break;

    case 115200:

        cfsetispeed(&newtio, B115200);

        cfsetospeed(&newtio, B115200);

        break;

    case 460800:

        cfsetispeed(&newtio, B460800);

        cfsetospeed(&newtio, B460800);

        break;

    default:

        cfsetispeed(&newtio, B9600);

        cfsetospeed(&newtio, B9600);

        break;

    }

    /*设置停止位*/

    if( nStop == 1 )

        newtio.c_cflag &= ~CSTOPB;

    else if ( nStop == 2 )

        newtio.c_cflag |= CSTOPB;

    /*设置等待时间和最小接收字符*/

    newtio.c_cc[VTIME] = 0;

    newtio.c_cc[VMIN] = 0;

    /*处理未接收字符*/

    tcflush(fd,TCIFLUSH);

    /*激活新配置*/

    if((tcsetattr(fd,TCSANOW,&newtio))!=0)

    {

        perror("com set error");

        return -1;

    }

    printf("set done!\n");

    return 0;

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void put_char(  char buffer)
{
    write(fd,&buffer,1);//写串口
}
void send(char *p)
{
    while(*p!='\0'){put_char(*p);p++;}
}
unsigned char get_char(void)
{
    unsigned char ch=0;
    while(ch==0)
        read(fd,&ch,1);

    return ch;
}




void Delay_1ms(uint j) 	 //延时1ms
{ 
    while(j--)
        usleep(1000);
}

void Delay_100us(uint j) 	 //?100us
{ 	
    while(j--)
        usleep(100);

}
/**/


int cols() 
{
    return 30;
}

int rows()
{
    return 7;
}

void  adjust(int *col, int *row){
    if(*col==-1)  *col = 30;
    if((*col<-1)||(*col>30))
        assert(0);
    if(*row==-1)   *row = 7;
    if((*row<-1)||(*row>7))
        assert(0);
    //assert
}

void change(int a,char b,char *temp)
{
    char bai,shi,ge;
    bai=shi=ge=0;
    a=a*32;
    bai=a/100;
    shi=a%100/10;
    ge=a%10;
    /*
    printf("bai=%d",bai);
    printf("shi=%d",shi);
    printf("ge=%d",ge);
    */
    temp[b]=bai+'0';
    temp[b+1]=shi+'0';
    temp[b+2]=ge+'0';
}
/*
    PL(x1,y1,x2,y2,c);
*/
int lcd_line(int x1,int y1,int x2,int y2)
{
    char temp[]="PL(000,000,000,000,003);";
    change(x1,3,temp);
    change(y1,7,temp);
    change(x2,11,temp);
    change(y2,15,temp);
#ifdef TEST_LCD
    printf("lcd-lcd_line-temp=%s\n",temp);
#endif
    send(temp);
    return 0;
}
/*
*函数名：void lcd_clear(int top, int left, int bottom, int right)
*函数作用：清屏
*参数类型：int top, int left, int bottom, int right
*参数范围：top<bottom<=7  left<right<=30
*说明：BOX(x1,y1,x2,y2,c);
*/
int lcd_clear_rect(int x1,  int y1,int x2, int y2)
{

    if(x1>=x2) printf("lcd_clear error!!! \n" );
    if(y1>=y2) printf("lcd_clear error!!! \n");
    if(x1>=27) x1=27;
    if(y1>=14) y1=14;
    char temp[]="BOXF(000,000,000,000,007);";
    change(x1,5,temp);
    change(y1,9,temp);
    change(x2,13,temp);
    change(y2,17,temp);
    printf("lcd_clear=%s\n",temp);
    send(temp);
    return 0;
}

/*
*函数名：lcd_cursor(int row, int col, int len)
*函数作用：反显
*参数类型：int row, int col, int len
*参数范围：0<=row<=7  0<=col<=30  0<=len<=30; 0<=col+len<=30
*说明：反显范围20*128*8个点
BOXF(x1,y1,x2,y2,c);BOXF(694,96,854,160,3);
*/
int lcd_cursor(int x, int y, int len)
{
    char temp[]="BOXF(000,000,000,000,3);";
    change(x,5,temp);
    change(y,9,temp);
    change(x+len,13,temp);
    change(y+1,17,temp);
#ifdef TEST_LCD
    printf("lcd-lcd_cursor-temp=%s\n",temp);
#endif
    send(temp);
    return 0;
}

/*
*函数名：lcd_poswrite(const uchar *str, int x, int y,int type)
*函数作用：显示字符串
*参数类型： const uchar *str, int col, int row
*参数范围:	str 1:以'\0'结尾 2:不能为空
                         0<=col<=7;  0<=row<30
DS32(192,0,'汉字',1);
*/
int lcd_poswrite(const char *str, int x, int y,int type)
{
#ifdef TEST_LCD
    printf("x=%d,y=%d,str=\n",x,y,str);
#endif
    char temp[]="DS32(000,000,'";

    /**/
    y=y-1;
    if(y==-1) y=MAX_Y;
    if(x==-1) x=MAX_X;
    x=x/2;

    if((strlen(str)+x)>27)
        printf("lcd-lcd_poswrite-temp x overflowoverflow!!!\n");
    if(y>14)
        printf("lcd-lcd_poswrite-temp y overflowoverflow!!!!\n");

    change(x,5,temp);
    change(y,9,temp);
    char *s=(char *)malloc(strlen(str)+50);
    if(s==NULL)
    {
        printf("lcd-lcd_poswrite-temp y char *s=(char *)malloc(strlen(str)+14); !!!!\n");
        return -1;
    }
    strcpy(s,temp);
    strcat(s,str);
    if(type==1)
    {
        strcat(s,"',1);");
    }
    else
    {
        strcat(s,"',3);");
    }
#ifdef TEST_LCD

    printf("lcd-lcd_poswrite-s=%s\n",s);
#endif
    send(s);
    free(s);




    return 0;
}




void  end()
{
    lcd_line(0,1,27,1);
    lcd_line(0,2,27,2);
    lcd_line(0,3,27,3);

    lcd_line(20,5,27,5);
    lcd_line(20,7,27,7);
    lcd_line(20,9,27,9);
    lcd_line(20,11,27,11);

    lcd_line(0,14,27,14);
    lcd_line(0,13,27,13);



    lcd_line(10,13,10,15);
    lcd_line(20,3,20,15);

    send("\r\n");

}
/*
*函数名：int lcd_init()
*函数作用：屏幕初始化
*参数类型：无
*参数范围：无
*/
int lcd_init()
{
    int i;
    if((fd=open_port(fd,1))<0){

        perror("open_port error");
        return 0;
    }
    printf("fd=open_port(fd,1)");

    if((i=set_opt(fd,115200,8,'N',1))<0){
        perror("set_opt error");
        return 0;
    }
    send("CLS(7);");
    end();

    return 0;
}

int lcd_clear_all()
{
    send("CLS(7);");
    return 0;
}

/*
int main()
{
 lcd_init();

 lcd_poswrite("shajun是12",22,3,1);


 lcd_poswrite("shajun是12",1,1,1);
 lcd_poswrite("shajun是12",2,2,1);
 lcd_poswrite("shajun是12",3,3,1);
 lcd_poswrite("shajun是12",3,3,0);
 lcd_clear(0,0,3,3);

 end();
}*/
/*
新液晶
分辨率：854*480
显示范围：(x,y)(27,14)

*/
/*
int VirtualPaintEngine::writeText(QRect rect, const QString &text, Color fontColor, Color backColor)
{
    QColor font_color(fontColor.r, fontColor.g, fontColor.b);
    QColor back_color(backColor.r, backColor.g, backColor.b);

    int x = rect.x(), y = rect.y();
    if(x>=SCREEN_WIDTH||x<0||y>=SCREEN_HEIGHT||y<0){
        qWarning() << Q_FUNC_INFO << "Position out of range, x:"<< x <<"y:" << y;
        return false;
    }
    int type=1;
    int maxX = qMin(SCREEN_WIDTH, x+text.length());
    if(fontColor!= **)
     type=0;


    return lcd_poswrite(text, int x, int y,int type);
}


int VirtualPaintEngine::clearRect(QRect rect)
{
    int x = rect.x(), y = rect.y(), width = rect.width(), height = rect.height();
    int maxX = qMin(x+width, SCREEN_WIDTH);
    int maxY = qMin(y+height, SCREEN_HEIGHT);
    int x2=x+width;
    int y2=y+height;

    return lcd_clear( x,  y, x2,  y2);
}
/home/firemiles/x-tools/arm-firemiles-linux-gnueabi/arm-firemiles-linux-gnueab/sysroot/Qt5.5/bin/qmake

*/

